﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace DNA.Mvc.jQuery
{
    public class ButtonBuilder : jQueryComponentBuilder<ButtonExOptions, Button, ButtonBuilder>
    {
        public ButtonBuilder(Button component, ViewContext viewContext, IViewDataContainer viewContainer) : base(component, viewContext, viewContainer) { }

        protected override string jQueryPluginName
        {
            get { return "buttonex"; }
        }

        public ButtonBuilder ChangeType(ButtonTypes type)
        {
            if (type == ButtonTypes.CheckBox)
                Component.HasValue = true;
            this.Options(opts =>
            {
                opts.ButtonType = type;
            });
            return this;
        }
        
        public ButtonBuilder Group(string groupName)
        {
            return this.Group(groupName, null);
        }

        public ButtonBuilder Group(string groupName,string groupContainer)
        {
            Options(opts => {
                opts.GroupName =groupName;
                opts.GroupContainer = groupContainer;
            });
            return this;
        }

        public ButtonBuilder Text(string text)
        {
            Component.Text = text;
            return this;
        }

        public ButtonBuilder Submit()
        {
            Options(opts => { opts.IsSubmitButton = true; });
            return this;
        }

        public ButtonBuilder Icons(string primaryIcon)
        {
            return this.Icons(primaryIcon, null);
        }

        public ButtonBuilder Icons(string primaryIcon, string secondaryIcon)
        {
            Options(opts =>
            {
                opts.PrimaryIconCssClass = primaryIcon;
                opts.SecondaryIconCssClass = secondaryIcon;
            });
            return this;
        }

        public ButtonBuilder ImageIcons(string primaryIconUrl)
        {
            return this.ImageIcons(primaryIconUrl, null);
        }

        public ButtonBuilder ImageIcons(string primaryIconUrl, string secondaryIconUrl)
        {
            Options(opts =>
            {
                opts.PrimaryIconImageUrl = primaryIconUrl;
                opts.SecondaryIconImageUrl = secondaryIconUrl;
            });
            return this;
        }

        public ButtonBuilder Images(string url)
        {
            return this.Images(url, null, null);
        }

        public ButtonBuilder Images(string url, string hoverUrl)
        {
            return this.Images(url, hoverUrl, null);
        }

        public ButtonBuilder Images(string url, string hoverUrl, string clickUrl)
        {
            Options(opts =>
            {
                opts.ImageUrl = url;
                opts.HoverImageUrl = hoverUrl;
                opts.MouseDownImageUrl = clickUrl;
            });
            return this;
        }

        public ButtonBuilder ShowSplitButton(string onClick)
        {
            Options(opts => {
                opts.ShowSplitButton = true;
                opts.OnSplitButtonClick = onClick;
            });
            return this;
        }

        public ButtonBuilder IsBackground(bool bg)
        {
            Options(opts => { opts.IsBackgroundImage = bg; });
            return this;
        }

        public ButtonBuilder NavigateUrl(string url)
        {
            Options(opts => { opts.NavigateUrl = url; });
            return this;
        }

        public ButtonBuilder Click(string scripts)
        {
            Options(opts =>
            {
                opts.OnClick = scripts;
            });
            return this;

        }

        public ButtonBuilder Click(StringBuilder scripts)
        {
            return this.Click(scripts.ToString());
        }

        public ButtonBuilder State(object value)
        {
            return this;
        }

        public ButtonBuilder States(Action<ButtonStateFactory> states)
        {
            var fac = new ButtonStateFactory();
            states.Invoke(fac);
            Component.States = fac.States;
            return this;
        }

        public override void Render()
        {
            _InitComponent();
            RenderComponent();
            _InitScripts();
        }

        public override MvcHtmlString GetHtml()
        {
            _InitComponent();
            var _html = MvcHtmlString.Create(Component.GetHtml());
            _InitScripts();
            return _html;
        }

        private void _InitComponent()
        {
            if (options != null)
            {
                if (options.IsSubmitButton)
                    options.OnClick = "$(this).closest('form').submit();";
                if (options.Value != null)
                {
                    if (options.Value.GetType().Equals(typeof(bool)))
                        Component.Value = options.Value.ToString().ToLower();
                    else
                        Component.Value = options.Value.ToString();
                    Component.HasValue = true;
                }
            }

            if (Component.States.Count > 0)
            {
                ButtonState _selectedState = null;

                foreach (var state in Component.States)
                {
                    if (state.Selected)
                    {
                        _selectedState = state;
                        break;
                    }
                }

                if (_selectedState == null)
                {
                    _selectedState = Component.States[0];
                    Component.Value = _selectedState.Value as string;
                }

                Options(opts =>
                {
                    opts.ImageUrl = _selectedState.ImageUrl;
                    opts.PrimaryIconCssClass = _selectedState.PrimaryIconCssCass;
                    opts.PrimaryIconImageUrl = _selectedState.PrimaryIconImageUrl;
                    opts.SecondaryIconCssClass = _selectedState.SecondaryIconCssClass;
                    opts.SecondaryIconImageUrl = _selectedState.SecondaryIconImageUrl;

                    if (!string.IsNullOrEmpty(_selectedState.CssClass))
                    {
                        if (Component.HtmlAttributes.ContainsKey("class"))
                            Component.HtmlAttributes["class"] += " " + _selectedState.CssClass;
                        else
                            Component.HtmlAttributes.Add("class", _selectedState.CssClass);
                    }

                    if (!string.IsNullOrEmpty(_selectedState.Text))
                        Component.Text = _selectedState.Text;


                });

                Component.HasValue = true;
            }
        }

        private void _InitScripts()
        {
            if (Component.States.Count > 0)
            {
                var scripts = new jQueryScriptBuilder("#" + Component.Id, jQueryPluginName);

                if (options != null)
                    scripts.AddOptions(options);

                var _states = from state in Component.States
                              select new
                              {
                                  text = state.Text,
                                  imageUrl = state.ImageUrl,
                                  primaryIconImage = state.PrimaryIconImageUrl,
                                  primaryIcon = state.PrimaryIconCssCass,
                                  secondaryIcon = state.SecondaryIconCssClass,
                                  secondaryIconImage = state.SecondaryIconImageUrl,
                                  value = state.Value == null ? "" : state.Value,
                                  cssclass = state.CssClass,
                                  selected = state.Selected
                              };

                string json = (new JavaScriptSerializer()).Serialize(_states.ToArray());
                scripts.AddOption("states", json, false);

                if ((options.ButtonType == ButtonTypes.RadioBox) || ((options.IsRadio.HasValue) && (options.IsRadio.Value)))
                {
                    if (!scripts.Options.ContainsKey("radio"))
                        scripts.AddOption("radio", true);
                }

                Helper.RegisterStartupScript(scripts.ToString());
            }
            else
                Helper.jQuery(Component.Id, jQueryPluginName, options);
        }
    }
}
